package com.ddw.meedeeuh.shared.database.sqlite;

import com.almworks.sqlite4java.SQLiteException;
import com.almworks.sqlite4java.SQLiteStatement;

/**
 * Represents a utilities class for sqlite, it includes methods to help
 * parse values from a sqlite statement
 * @author cmcnicholas
 *
 */
public abstract class SQLiteUtils {

	/**
	 * Gets a nullable string field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a string or null
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static String getNullableString(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnNull(index) ? null : getString(statement, index);
	}

	/**
	 * Gets a nullable integer field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return an integer or null
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static Integer getNullableInt(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnNull(index) ? null : getInt(statement, index);
	}

	/**
	 * Gets a nullable boolean field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a boolean or null
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static Boolean getNullableBoolean(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnNull(index) ? null : getBoolean(statement, index);
	}

	/**
	 * Gets a nullable double field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a double or null
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static Double getNullableDouble(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnNull(index) ? null : getDouble(statement, index);
	}

	/**
	 * Gets a string field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a string
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static String getString(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnString(index);
	}

	/**
	 * Gets an integer field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a integer
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static int getInt(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnInt(index);
	}

	/**
	 * Gets a boolean field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a boolean
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static boolean getBoolean(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnInt(index) == 1;
	}

	/**
	 * Gets a double field value from a sqlite statement
	 * @param statement the sqlite statement to get the value from
	 * @param index the index of the column
	 * @return a double
	 * @throws SQLiteException if there is a problem reading the value
	 */
	public static double getDouble(SQLiteStatement statement, int index) throws SQLiteException {
		if(statement == null) {
			throw new IllegalArgumentException("The statement parameter cannot be null");
		}
		if(index < 0) {
			throw new IndexOutOfBoundsException("The index parameter cannot be less than zero");
		}

		return statement.columnDouble(index);
	}

	/**
	 * Binds a nullable parameter to a sqlite statement
	 * @param statement the statement to bind to
	 * @param index the index to bind at
	 * @param value the nullable value
	 * @throws SQLiteException an exception if there is a problem binding the value
	 */
	public static void bindNullable(SQLiteStatement statement, int index, String value) throws SQLiteException {
		if(value == null) {
			statement.bindNull(index);
		} else {
			statement.bind(index, value);
		}
	}

	/**
	 * Binds a nullable parameter to a sqlite statement
	 * @param statement the statement to bind to
	 * @param index the index to bind at
	 * @param value the nullable value
	 * @throws SQLiteException an exception if there is a problem binding the value
	 */
	public static void bindNullable(SQLiteStatement statement, int index, Integer value) throws SQLiteException {
		if(value == null) {
			statement.bindNull(index);
		} else {
			statement.bind(index, value.intValue());
		}
	}

	/**
	 * Binds a nullable parameter to a sqlite statement
	 * @param statement the statement to bind to
	 * @param index the index to bind at
	 * @param value the nullable value
	 * @throws SQLiteException an exception if there is a problem binding the value
	 */
	public static void bindNullable(SQLiteStatement statement, int index, Double value) throws SQLiteException {
		if(value == null) {
			statement.bindNull(index);
		} else {
			statement.bind(index, value.doubleValue());
		}
	}

	/**
	 * Binds a nullable parameter to a sqlite statement
	 * @param statement the statement to bind to
	 * @param index the index to bind at
	 * @param value the nullable value
	 * @throws SQLiteException an exception if there is a problem binding the value
	 */
	public static void bindNullable(SQLiteStatement statement, int index, Boolean value) throws SQLiteException {
		if(value == null) {
			statement.bindNull(index);
		} else {
			bindNullable(statement, index, value ? 1 : 0);
		}
	}

}
